package com.xiaoshuidi.cloud.module.member.service.coupon;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xiaoshuidi.cloud.framework.common.exception.ServiceException;
import com.xiaoshuidi.cloud.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.xiaoshuidi.cloud.framework.common.pojo.PageResult;
import com.xiaoshuidi.cloud.framework.common.util.json.JsonUtils;
import com.xiaoshuidi.cloud.framework.mybatis.core.util.MyBatisUtils;
import com.xiaoshuidi.cloud.framework.redis.lock.DistributeLock;
import com.xiaoshuidi.cloud.framework.security.core.util.SecurityFrameworkUtils;
import com.xiaoshuidi.cloud.framework.tenant.core.util.TenantUtils;
import com.xiaoshuidi.cloud.module.contract.api.ContractApi;
import com.xiaoshuidi.cloud.module.member.api.coupon.vo.*;
import com.xiaoshuidi.cloud.module.member.controller.admin.coupon.vo.*;
import com.xiaoshuidi.cloud.module.member.controller.app.coupon.vo.BillCheckCouponsVo;
import com.xiaoshuidi.cloud.module.member.controller.app.coupon.vo.CouponCustomerValidQueryVo;
import com.xiaoshuidi.cloud.module.member.controller.app.coupon.vo.CouponCustomerVo;
import com.xiaoshuidi.cloud.module.member.controller.app.coupon.vo.CouponSimpleInfoVo;
import com.xiaoshuidi.cloud.module.member.convert.coupon.CouponConvert;
import com.xiaoshuidi.cloud.module.member.enums.coupon.CouponTypeEnum;
import com.xiaoshuidi.cloud.module.member.enums.coupon.CouponUsageStatusEnum;
import com.xiaoshuidi.cloud.module.member.enums.coupon.CouponUsegeTimeTypeEnum;
import com.xiaoshuidi.cloud.module.member.mapper.coupon.CouponCustomerMapper;
import com.xiaoshuidi.cloud.module.member.mapper.coupon.CouponMapper;
import com.xiaoshuidi.cloud.module.member.mapper.coupon.CouponRecordMapper;
import com.xiaoshuidi.cloud.module.member.pojo.coupon.CouponCustomerEntity;
import com.xiaoshuidi.cloud.module.member.pojo.coupon.CouponEntity;
import com.xiaoshuidi.cloud.module.member.pojo.coupon.CouponRecordEntity;
import com.xiaoshuidi.cloud.module.member.pojo.user.MemberUser;
import com.xiaoshuidi.cloud.module.member.repository.MemberCouponCustomerRepository;
import com.xiaoshuidi.cloud.module.member.repository.MemberCouponRecordRespository;
import com.xiaoshuidi.cloud.module.member.repository.MemberCouponRepository;
import com.xiaoshuidi.cloud.module.member.repository.MemberUserRepository;
import com.xiaoshuidi.cloud.module.member.service.user.MemberUserService;
import com.xiaoshuidi.cloud.module.member.util.CodeUtil;
import com.xiaoshuidi.cloud.module.member.util.CustomDateUtil;
import com.xiaoshuidi.cloud.module.member.utils.CommonTenantIdVo;
import com.xiaoshuidi.cloud.module.member.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.xiaoshuidi.cloud.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.xiaoshuidi.cloud.module.member.enums.ErrorCodeConstants.*;

/**
 * @author Alex
 * @version generator
 * @description 客户优惠券service层
 * @date 2023-03-15 15:02:02
 */
@Service
@Slf4j
public class CouponCustomerService {
    public static final String DEDUCE_COUPONS_LOCK = "coupons:deduce:lock";//扣减优惠券的锁
    public static final String CANCEL_COUPONS_LOCK = "coupons:cancel:lock";//取消发放优惠券的锁
    public static final String UNTIE_COUPONS_LOCK = "coupons:untie:lock"; // 优惠劵解锁
    public static final String ADD_COUPONS_LOCK = "coupons:add:lock";// 优惠劵加锁
    public static final String UPDATE_COUPONS_LOCK = "coupons:update:lock"; //支付成功后更新优惠劵
    @Resource
    CouponMapper couponMapper;
    @Resource
    CouponCustomerMapper couponCustomerMapper;
    @Resource
    CouponRecordMapper couponRecordMapper;
    @Resource
    StringRedisTemplate stringRedisTemplate;
    @Resource
    MemberUserService userService;
    @Resource
    CouponCustomerMapper baseMapper;
    @Resource
    ContractApi contractApi;

    @Resource
    private MemberCouponRepository memberCouponRepository;

    @Resource
    private MemberCouponRecordRespository memberCouponRecordRespository;

    @Resource
    private MemberCouponCustomerRepository memberCouponCustomerRepository;


    @Resource
    private MemberUserRepository memberUserRepository;

    @Resource
    private CodeUtil codeUtil;


    //发放优惠券
    @Transactional(rollbackFor = Exception.class)
    public void saveCouponCustomer(CouponEntity couponDto, CouponCustomerInsVo dto, String oldPhone) {
        //根据客户手机号查询客户信息
        MemberUser tenantUserDto = userService.getUserByMobile(dto.getUserPhone());
        if (tenantUserDto == null) {
            throw exception(USER_NOT_EXISTS);
        }
        log.info("优惠券发放量：{}", dto.getCouponNum());
        Long surplusStock = couponDto.getSurplusStock();
        //判断优惠券的数量是否够发放
        if (surplusStock != -1 && surplusStock < dto.getCouponNum()) {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "库存不够发!");
        }
        dto.setCouponId(couponDto.getId());
        dto.setCouponUsage(couponDto.getCouponUsage());
        dto.setStock(couponDto.getStock());
        dto.setSurplusStock(couponDto.getSurplusStock());
        //减库存
//        decreaseInventory(dto);
        if (dto.getStock().intValue() != -1) {
            memberCouponRepository.deduceStock(dto.getCouponId(), dto.getCouponNum());
        }
        //发券
        dto.setCouponUsageTimeType(couponDto.getCouponUsageTimeType());
        dto.setCouponUsageTime(couponDto.getCouponUsageTime());
        if (dto.getCouponUsageTimeType() != 2) {
            dto.setExpirationStartTime(couponDto.getExpirationStartTime());
            dto.setExpirationEndTime(couponDto.getExpirationEndTime());
        } else {
            Date expirationStartTime = new Date();
            dto.setExpirationStartTime(expirationStartTime);
            dto.setExpirationEndTime(DateUtils.addDateDays(expirationStartTime, dto.getCouponUsageTime()));
        }

        dto.setCouponType(couponDto.getCouponType());
        //设折扣和折扣金额
        dto.setPreferentialContentType(couponDto.getPreferentialContentType());
        dto.setPreferentialAmount(couponDto.getMarginPreference());
        dto.setUserId(tenantUserDto.getId());
        dto.setUserName(tenantUserDto.getName());
        issueCoupons(dto);
        voucherIssuanceRecord(dto, couponDto.getCouponName());
    }

    //发券
    private void issueCoupons(CouponCustomerInsVo dto) {
        CouponCustomerEntity couponCustomerEntity = CouponConvert.INSTANCE.convert(dto);
        Date expirationStartTime;
        Date expirationEndTime;
        //多少天内有效
        if (CouponUsegeTimeTypeEnum.DAYS_VALID.equals(dto.getCouponUsageTimeType())) {
            expirationStartTime = new Date();
            expirationEndTime = DateUtils.addDateDays(expirationStartTime, dto.getCouponUsageTime());
        } else {
            expirationStartTime = dto.getExpirationStartTime();
            expirationEndTime = dto.getExpirationEndTime();
        }
        couponCustomerEntity.setExpirationEndTime(expirationStartTime);
        couponCustomerEntity.setExpirationEndTime(expirationEndTime);
        String couponCode = CouponTypeEnum.getCouponTypeByCode(dto.getCouponType());
        String key = couponCode + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));

        for (int i = 0; i < dto.getCouponNum(); i++) {
            couponCustomerEntity.setId(null);
            String sequencecode = codeUtil.queryMaxCouponCode(key);
            String value = key + sequencecode;
            couponCustomerEntity.setCouponCode(value);
            couponCustomerMapper.insert(couponCustomerEntity);
        }
    }

    //发券记录 voucher_issuance_Record
    private void voucherIssuanceRecord(CouponCustomerInsVo dto, String couponName) {
        CouponRecordEntity couponRecordEntity = new CouponRecordEntity();
        couponRecordEntity.setCouponId(dto.getCouponId());
        couponRecordEntity.setIssuerName(dto.getUserName());
        couponRecordEntity.setIssuerAccount(dto.getUserPhone());
        Long couponNum = dto.getCouponNum();
//        if (CouponTypeEnum.OLD_WITH_NEW_DISCOUNT.getCode().equals(dto.getCouponType())) {
//            couponNum = couponNum * 2;
//        }
        couponRecordEntity.setCouponName(couponName);
        couponRecordEntity.setIssuerNum(couponNum);
        couponRecordEntity.setRemarks(dto.getRemarks());
        couponRecordEntity.setCouponUrl(JSONObject.toJSONString(dto.getCouponUrls()));
        couponRecordMapper.insert(couponRecordEntity);
    }

    //减库存
    private void decreaseInventory(CouponCustomerInsVo dto) {

        CouponEntity couponEntity = new CouponEntity();
        couponEntity.setId(dto.getCouponId());
        // 优惠券使用量+发券数量
        Long couponNum = dto.getCouponNum();
//        Long couponUsage = dto.getCouponUsage() + couponNum;
        //设置使用量
//        couponEntity.setCouponUsage(couponUsage);
        if (dto.getStock().intValue() != -1) {
            couponEntity.setSurplusStock(dto.getSurplusStock() - couponNum);
        }
        LambdaQueryWrapper<CouponEntity> qw = new LambdaQueryWrapper();
        qw.eq(CouponEntity::getId, dto.getCouponId()).eq(dto.getStock().intValue() != -1, CouponEntity::getSurplusStock, dto.getSurplusStock());
        couponMapper.update(couponEntity, qw);
    }


    //查询可用优惠券
    public List<CouponCustomerValidQueryVo> queryAbledCoupon(Long tenantUserId) {
        Date date = new Date();
        List<CouponCustomerValidQueryVo> couponCustomerVos = couponCustomerMapper.queryAbledCoupon(tenantUserId, date);
        return couponCustomerVos;
    }

    //查询不可用优惠券
    public List<CouponCustomerValidQueryVo> queryDisabledCoupon(Long tenantUserId) {
        Date date = new Date();
        List<CouponCustomerValidQueryVo> couponCustomerVos = couponCustomerMapper.queryDisabledCoupon(tenantUserId, date);
        return couponCustomerVos;
    }

    // 优惠券核销
    public void couponCustomerUse(CouponCustomerUseForm form) {
        form.getItem().forEach(item -> {
            LambdaQueryWrapper<CouponCustomerEntity> qw = new LambdaQueryWrapper();
            qw.eq(CouponCustomerEntity::getCouponCode, item.getCouponCode());
            CouponCustomerEntity couponCustomerEntity = new CouponCustomerEntity();
            couponCustomerEntity.setUsageStatus(CouponUsageStatusEnum.USED.getCode());
            couponCustomerEntity.setUsageTime(new Date());
            couponCustomerEntity.setRelevanceContract(item.getRelevanceContract());
            couponCustomerEntity.setRelevanceBill(item.getRelevanceBill());
            couponCustomerEntity.setPreferentialAmount(item.getPreferentialAmount());
            couponCustomerMapper.update(couponCustomerEntity, qw);
        });

    }

    /**
     * 作废用户优惠券
     *
     * @param customerCouponId 用户优惠券id
     */
    public void cancel(Long customerCouponId) {
        CouponCustomerEntity couponCustomer = baseMapper.selectById(customerCouponId);
        if (CouponUsageStatusEnum.VOIDED.getCode().equals(couponCustomer.getUsageStatus())) {
            throw exception(COUPON_DISABLE);
        }
        if (CouponUsageStatusEnum.USED.getCode().equals(couponCustomer.getUsageStatus())) {
            throw exception(COUPON_USED);
        }
        //已过期
        if (CouponUsageStatusEnum.EXPIRED.getCode().equals(couponCustomer.getUsageStatus()) || DateUtil.compare(new Date(), couponCustomer.getExpirationEndTime()) > 0) {
            throw exception(COUPON_EXPIRE);
        }
        couponCustomer.setUsageStatus(CouponUsageStatusEnum.VOIDED.getCode());
        baseMapper.updateById(couponCustomer);
    }

    /**
     * 租客优惠券列表
     */
    public List<CouponCustomerVo> couponCustomer(Long tenantUserId, Integer usageStatus) {
        return baseMapper.selectCouponByCustomer(tenantUserId, usageStatus);
    }

    //更加ids 查询
    public List<CouponCustomerInfoVo> queryByIds(List ids) {
        List<CouponCustomerInfoVo> couponCustomerValidQueryEntities = baseMapper.queryByIds(ids);
        return couponCustomerValidQueryEntities;
    }

    public PageResult<CouponCustomerVo> getCustomerCouponList(CouponCustomerPageForm form) {
        IPage<CouponCustomerVo> page = MyBatisUtils.buildPage(form);
        List<CouponCustomerVo> list = baseMapper.selectCustomerCouponList(page, form);
        PageResult<CouponCustomerVo> pageResult = new PageResult(list, page.getTotal());
        pageResult.setList(list);
        return pageResult;
    }

    public List<CouponCustomerVo> exportCustomerCouponList(CouponCustomerPageForm form) {
        return baseMapper.selectCustomerCouponList(form);
    }

    public PageResult<CouponCustomerVo> getTenantCoupons(CommonTenantIdVo vo) {
        IPage<CouponCustomerVo> page = MyBatisUtils.buildPage(vo);
        List<CouponCustomerVo> list = baseMapper.selectTenantCoupons(page, vo);
        PageResult<CouponCustomerVo> pageResult = new PageResult(list, page.getTotal());
        pageResult.setList(list);
        return pageResult;
    }

    public BillCheckCouponsVo getCouponsByBills(Long billId) {
        BillCheckCouponsVo vo = new BillCheckCouponsVo();
        //当前优惠券
        List<CouponCustomerValidQueryVo> coupons = this.queryAbledCoupon(SecurityFrameworkUtils.getLoginUserId());
        if (CollectionUtils.isNotEmpty(coupons)) {
            //账单明细 缺接口
            //CommonResult result = contractApi.ge
            List<CouponCustomerValidQueryVo> available = new ArrayList<>();
            List<CouponCustomerValidQueryVo> disable = new ArrayList<>();
            for (CouponCustomerValidQueryVo coupon : coupons) {
                //TODO 优惠券使用判断
            }
            vo.setAvailable(available);
            vo.setDisable(disable);
        }
        return vo;

    }

    /**
     * 判断是否自动发放预定优惠券
     *
     * @param bookingCouponSendVO
     */
    @Transactional(rollbackFor = Exception.class)
    public void validBookingSendCoupon(BookingCouponSendVO bookingCouponSendVO) {
        try (DistributeLock lock = DistributeLock.getLock(DEDUCE_COUPONS_LOCK + ":" + bookingCouponSendVO.getUserId())) {
            if (lock.tryLock()) {
                TenantUtils.execute(bookingCouponSendVO.getTenantId(), () -> {
                    log.info("################################发预定券" + JsonUtils.toJsonString(bookingCouponSendVO));
                    //查看是否符合发放条件
                    CouponEntity coupon = memberCouponRepository.validBookingSendCoupon(bookingCouponSendVO);
                    log.info("################################发预定券券对象" + JsonUtils.toJsonString(coupon));
                    if (coupon != null && (coupon.getStock().intValue() == -1 || coupon.getSurplusStock().intValue() > 0)) {
                        //加分布式锁
                        //根据用户id,查询用户信息
                        MemberUser user = memberUserRepository.getById(bookingCouponSendVO.getUserId());
                        //自动发放预定优惠券且只发给用户id一张券
                        CouponRecordEntity couponRecordEntity = memberCouponRecordRespository.sendCouponRecord(coupon, user.getMobile(), CouponTypeEnum.RESERVATION_DISCOUNT.getNum());
                        log.info("################################发预定券记录成功" + JsonUtils.toJsonString(couponRecordEntity));

                        memberCouponCustomerRepository.sendBookingCoupon(bookingCouponSendVO, coupon, user, couponRecordEntity);


                        //扣减库存
                        if (coupon.getStock().intValue() > 0) {
                            memberCouponRepository.deduceStock(coupon.getId(), 1L);
                            log.info("################################扣减库存成功");
                        } else {
                            memberCouponRepository.addSendStock(coupon.getId(), 1L);
                        }
                        //加分布式锁
                    }
                    //ignore
                });
            }
        }
    }

    /**
     * 取消预定发送的优惠券
     *
     * @param reserveCancelMessage
     */
    @Transactional(rollbackFor = Exception.class)
    public void cancelBookingCoupon(CancelBookingCouponSendVO reserveCancelMessage) {
        try (DistributeLock lock = DistributeLock.getLock(CANCEL_COUPONS_LOCK + ":" + reserveCancelMessage.getUserId())) {
            if (lock.tryLock()) {
                TenantUtils.execute(reserveCancelMessage.getTenantId(), () -> {
                    //判断这个用户有没有发送给关于业务主键相关的预定优惠券
                    log.info("################################取消发预定券" + JsonUtils.toJsonString(reserveCancelMessage));
                    List<CouponCustomerEntity> list = memberCouponCustomerRepository.cancelBookingCoupon(reserveCancelMessage);
                    if (list != null && list.size() > 0) {
                        int size = list.size();//取消了几张券
                        Long couponId = list.get(0).getCouponId();
                        List<Long> collect = list.stream().map(CouponCustomerEntity::getId).collect(Collectors.toList());
                        memberCouponCustomerRepository.removeBatchByIds(collect);
                        //取消发放记录
                        List<Long> recordIds = list.stream().map(CouponCustomerEntity::getRecordId).collect(Collectors.toList());
                        memberCouponRecordRespository.removeBatchByIds(recordIds);
                        //还原优惠库存
                        CouponEntity coupon = memberCouponRepository.getById(couponId);
                        if (coupon.getStock().intValue() > 0) {
                            memberCouponRepository.addStock(coupon.getId(), Long.valueOf(size));
                        } else {
                            memberCouponRepository.deduceSendStock(coupon.getId(), Long.valueOf(size));
                        }
                    }
                    //ignore message
                });
            }
        }
    }

    /**
     * 判断是否自动发放老带新优惠券
     *
     * @param oldBringNewCouponSendVO
     */
    public void validOldBringsNewSendCoupon(OldBringNewCouponSendVO oldBringNewCouponSendVO) {
        try (DistributeLock lock = DistributeLock.getLock(DEDUCE_COUPONS_LOCK + ":" + oldBringNewCouponSendVO.getNewUserId())) {
            //todo 如果
            if (lock.tryLock()) {
                TenantUtils.execute(oldBringNewCouponSendVO.getTenantId(), () -> {
                    log.info("################################发老带新券" + JsonUtils.toJsonString(oldBringNewCouponSendVO));
                    //查看是否符合发放条件有限制数量
                    //老和新在同一个门店，以新客门店为发放判断条件
//                if (oldBringNewCouponSendVO.getOldApartmentId().intValue() == oldBringNewCouponSendVO.getNewApartmentId().intValue()) {
                    CouponEntity coupon = memberCouponRepository.validOldBringsNewSendCoupon(oldBringNewCouponSendVO);
                    if (coupon != null) {
                        //如果库存大于等于2,新老客都发券，
                        int oldOwnNum = memberCouponCustomerRepository.getOldBringsNewNum(oldBringNewCouponSendVO, "old", coupon.getId());
                        int newOwnNum = memberCouponCustomerRepository.getOldBringsNewNum(oldBringNewCouponSendVO, "new", coupon.getId());
                        Long sendStock = coupon.getSurplusStock();
                        if (sendStock.intValue() >= 2 || sendStock.intValue() == -1) {
                            //发券数量
                            Long n = 0L;
                            //根据用户id,查询用户信息
                            if ((coupon.getQuantityLimit().intValue() > 0 &&
                                    coupon.getQuantityLimit().intValue() > oldOwnNum) || coupon.getQuantityLimit().intValue() == -1) {
                                MemberUser oldUser = memberUserRepository.getById(oldBringNewCouponSendVO.getOldUserId());
                                //自动发放优惠券且只发给用户id一张券
                                CouponRecordEntity oldCouponRecordEntity = memberCouponRecordRespository.sendCouponRecord(coupon, oldUser.getMobile(), CouponTypeEnum.OLD_WITH_NEW_DISCOUNT.getNum());
                                memberCouponCustomerRepository.sendOldBringsNewCoupon(oldBringNewCouponSendVO, coupon, oldUser, oldCouponRecordEntity, "old");
                                n++;
                            }
                            if ((coupon.getQuantityLimit().intValue() > 0 &&
                                    coupon.getQuantityLimit().intValue() > newOwnNum) || coupon.getQuantityLimit().intValue() == -1) {
                                MemberUser newUser = memberUserRepository.getById(oldBringNewCouponSendVO.getNewUserId());
                                CouponRecordEntity newCouponRecordEntity = memberCouponRecordRespository.sendCouponRecord(coupon, newUser.getMobile(), CouponTypeEnum.OLD_WITH_NEW_DISCOUNT.getNum());
                                memberCouponCustomerRepository.sendOldBringsNewCoupon(oldBringNewCouponSendVO, coupon, newUser, newCouponRecordEntity, "new");
                                n++;
                            }
                            //扣减库存
                            if (coupon.getStock().intValue() > 0) {
                                memberCouponRepository.deduceStock(coupon.getId(), n);
                            } else {
                                memberCouponRepository.addSendStock(coupon.getId(), n);
                            }
                        } else if (sendStock.intValue() == 1) {
                            Long n = 0L;
                            if ((coupon.getQuantityLimit().intValue() > 0 &&
                                    coupon.getQuantityLimit().intValue() > oldOwnNum) || coupon.getQuantityLimit().intValue() == -1) {
                                //如果只有一张只发老客
                                MemberUser oldUser = memberUserRepository.getById(oldBringNewCouponSendVO.getOldUserId());
                                //自动发放预定优惠券且只发给用户id一张券
                                CouponRecordEntity oldCouponRecordEntity = memberCouponRecordRespository.sendCouponRecord(coupon, oldUser.getMobile(), CouponTypeEnum.OLD_WITH_NEW_DISCOUNT.getNum());
                                memberCouponCustomerRepository.sendOldBringsNewCoupon(oldBringNewCouponSendVO, coupon, oldUser, oldCouponRecordEntity, "old");
                                n++;
                            }
                            //扣减库存
                            if (coupon.getStock().intValue() > 0) {
                                memberCouponRepository.deduceStock(coupon.getId(), n);
                            }
                        }
                    }
                    //ignore 两个都不发
//                }
//                else {
//                    //两个不是一个门店
//                    CouponEntity coupon = memberCouponRepository.validOldBringsNewSendCoupon(oldBringNewCouponSendVO, "old");
//                    if (coupon != null && (coupon.getSendStock().intValue() == -1 || coupon.getSendStock().intValue() > 1)) {
//
//                        int oldOwnNum=memberCouponCustomerRepository.getOldBringsNewNum(oldBringNewCouponSendVO,"old",coupon.getId());
//                        int n=0;
//                        if (coupon.getQuantityLimit().intValue()>0 &&
//                                coupon.getQuantityLimit().intValue()>oldOwnNum) {
//                            MemberUser oldUser = memberUserRepository.getById(oldBringNewCouponSendVO.getOldUserId());
//                            //自动发放预定优惠券且只发给用户id一张券
//                            CouponRecordEntity oldCouponRecordEntity = memberCouponRecordRespository.sendCouponRecord(coupon, oldUser.getMobile(), CouponTypeEnum.OLD_WITH_NEW_DISCOUNT.getNum());
//                            memberCouponCustomerRepository.sendOldBringsNewCoupon(oldBringNewCouponSendVO, coupon, oldUser, oldCouponRecordEntity, "old");
//                            n++;
//                        }
//                        //扣减库存
//                        if (coupon.getSendStock().intValue() > 0) {
//                            Long sendStock = coupon.getSendStock();
//                            sendStock = sendStock-n;
//                            memberCouponRepository.updateById(coupon);
//                        }
//                    }
//                    CouponEntity newCoupon = memberCouponRepository.validOldBringsNewSendCoupon(oldBringNewCouponSendVO, "new");
//                    if (newCoupon != null && (newCoupon.getSendStock().intValue() == -1 || newCoupon.getSendStock().intValue() > 1)) {
//                        int newOwnNum=memberCouponCustomerRepository.getOldBringsNewNum(oldBringNewCouponSendVO,"new",coupon.getId());
//                        int n=0;
//                        if (coupon.getQuantityLimit().intValue()>0 &&
//                                coupon.getQuantityLimit().intValue()>newOwnNum) {
//                            MemberUser newUser = memberUserRepository.getById(oldBringNewCouponSendVO.getNewUserId());
//                            //自动发放预定优惠券且只发给用户id一张券
//                            CouponRecordEntity newCouponRecordEntity = memberCouponRecordRespository.sendCouponRecord(coupon, newUser.getMobile(), CouponTypeEnum.OLD_WITH_NEW_DISCOUNT.getNum());
//                            memberCouponCustomerRepository.sendOldBringsNewCoupon(oldBringNewCouponSendVO, coupon, newUser, newCouponRecordEntity, "new");
//                            n++;
//                        }
//                        //扣减库存
//                        if (newCoupon.getSendStock().intValue() > 0) {
//                            Long sendStock = newCoupon.getSendStock();
//                            sendStock = sendStock-n;
//                            memberCouponRepository.updateById(newCoupon);
//                        }
//                    }
//                }
                });
            }
        }
    }

    /**
     * 判断是否自动发放新签约优惠券
     *
     * @param newSignCouponSendVO
     */
    public void validNewSignSendCoupon(NewSignCouponSendVO newSignCouponSendVO) {
        try (DistributeLock lock = DistributeLock.getLock(DEDUCE_COUPONS_LOCK + ":" + newSignCouponSendVO.getUserId())) {
            if (lock.tryLock()) {
                TenantUtils.execute(newSignCouponSendVO.getTenantId(), () -> {
                    log.info("################################发新签约券" + JsonUtils.toJsonString(newSignCouponSendVO));
                    //查看是否符合发放条件
                    CouponEntity coupon = memberCouponRepository.validNewSignSendCoupon(newSignCouponSendVO);
                    if (coupon != null && (coupon.getStock().intValue() == -1 || coupon.getSurplusStock().intValue() >= newSignCouponSendVO.getBillPeriods().intValue())) {
                        //每个账期发一张
                        Long num = newSignCouponSendVO.getBillPeriods().longValue();
                        //根据用户id,查询用户信息
                        MemberUser user = memberUserRepository.getById(newSignCouponSendVO.getUserId());
                        //自动发放优惠券
                        CouponRecordEntity couponRecordEntity = memberCouponRecordRespository.sendCouponRecord(coupon, user.getMobile(), CouponTypeEnum.NEW_SIGNING_DISCOUNT.getNum());
                        memberCouponCustomerRepository.sendNewSignCoupon(newSignCouponSendVO, coupon, user, couponRecordEntity, num.intValue());
                        //扣减库存
                        if (coupon.getStock().intValue() > 0) {
                            memberCouponRepository.deduceStock(coupon.getId(), num);
                            log.info("################################扣减库存1111111111111111111111111" + JsonUtils.toJsonString(newSignCouponSendVO));
                        } else {
                            memberCouponRepository.addSendStock(coupon.getId(), num);
                        }
                    } else if (coupon != null && coupon.getSurplusStock().intValue() < newSignCouponSendVO.getBillPeriods() && coupon.getSurplusStock().intValue() != -1) {
                        //券不够发，有多少张发多少张
                        int num = coupon.getSendStock().intValue();
                        //根据用户id,查询用户信息
                        MemberUser user = memberUserRepository.getById(newSignCouponSendVO.getUserId());
                        //自动发放优惠券
                        CouponRecordEntity couponRecordEntity = memberCouponRecordRespository.sendCouponRecord(coupon, user.getMobile(), CouponTypeEnum.NEW_SIGNING_DISCOUNT.getNum());
                        memberCouponCustomerRepository.sendNewSignCoupon(newSignCouponSendVO, coupon, user, couponRecordEntity, num);
                        //扣减库存
                        if (coupon.getStock().intValue() > 0) {
                            memberCouponRepository.deduceStock(coupon.getId(), coupon.getSurplusStock());
                            log.info("################################扣减库存222222222222222222222222222222222222222222" + JsonUtils.toJsonString(newSignCouponSendVO));
                        }
                    }
                    //ignore
                });
            }
        }
    }

    public Boolean updateCoupon(List<CouponUpdateVo> couponUpdateVos) {
        log.info("优惠券使用 {}", JsonUtils.toJsonString(couponUpdateVos));
        try (DistributeLock lock = DistributeLock.getLock(UPDATE_COUPONS_LOCK + ":" + SecurityFrameworkUtils.getLoginUserId())) {
            if (lock.tryLock()) {
                for (CouponUpdateVo couponUpdateVo : couponUpdateVos) {
                    Long id = couponUpdateVo.getId();
                    Date usageTime = couponUpdateVo.getUsageTime();
                    if (ObjectUtil.isEmpty(usageTime)) {
                        usageTime = new Date();
                    }
                    couponCustomerMapper.updateCoupon(id, usageTime);
                    QueryWrapper<CouponCustomerEntity> qw = new QueryWrapper<>();
                    qw.eq("id", couponUpdateVo.getId());
                    CouponCustomerEntity couponCustomerEntity = couponCustomerMapper.selectOne(qw);
                    Long couponId = couponCustomerEntity.getCouponId();
                    couponCustomerMapper.updateCouponUsage(couponId);
                }
            }
        }

        return true;
    }

    public List<CouponUpdateReturn> couponAddLock(CouponLockVo couponLockVo) {
        log.info("优惠卷加锁传参: {}", JsonUtils.toJsonString(couponLockVo));
        List<CouponUpdateReturn> list = new ArrayList<>();
        try (DistributeLock lock = DistributeLock.getLock(ADD_COUPONS_LOCK + ":" + SecurityFrameworkUtils.getLoginUserId())) {
            if (lock.tryLock()) {
                Date lockedTime = couponLockVo.getLockedTime();
                int lockedDuration = couponLockVo.getLockedDuration();
                String relevanceBill = couponLockVo.getBillId().toString();
                String relevanceContract = couponLockVo.getContractId().toString();
                String billNo = couponLockVo.getBillNo();
                BigDecimal totalAmount = couponLockVo.getTotalAmount();
                Set<Long> ids = couponLockVo.getIds();
                List<CustomCouponVO> customCouponVOS = new ArrayList<>();
                QueryWrapper<CouponCustomerEntity> qws = new QueryWrapper<>();
                qws.in("id",ids);
                List<CouponCustomerEntity> list1 = couponCustomerMapper.selectList(qws);
                for (CouponCustomerEntity couponCustomerEntity : list1) {
                    Long couponId = couponCustomerEntity.getCouponId();
                    Long id = couponCustomerEntity.getId();
                    CustomCouponVO vo = new CustomCouponVO();
                    vo.setCouponId(couponId);
                    vo.setId(id);
                    customCouponVOS.add(vo);
                }
                CouponCheckReqVo couponCheckReqVo = new CouponCheckReqVo();
                couponCheckReqVo.setCustomCouponVOS(customCouponVOS);
                couponCheckReqVo.setStoreId(couponLockVo.getStoreId());
                couponCheckReqVo.setTenantUserId(couponLockVo.getTenantUserId());
                Boolean aBoolean = checkBillCouponsOverlay(couponCheckReqVo);
                if (aBoolean) {
                    List<CouponEntityVO> entityList = new ArrayList<>();
                    for (CustomCouponVO customCouponVO : customCouponVOS) {
                        Long couponId = customCouponVO.getCouponId();
                        QueryWrapper<CouponCustomerEntity> qw =new QueryWrapper<>();
                        qw.eq("coupon_id",couponId);
                        List<CouponCustomerEntity> entities = couponCustomerMapper.selectList(qw);
                        if(CollectionUtil.isNotEmpty(entities)){
                            CouponCustomerEntity couponCustomerEntity = entities.get(0);
                            CouponEntityVO couponEntityVO = new CouponEntityVO();
                            couponEntityVO.setCouponCustomerId(customCouponVO.getId());
                            couponEntityVO.setPreferentialContentType(couponCustomerEntity.getPreferentialContentType());
                            couponEntityVO.setMarginPreference(couponCustomerEntity.getPreferentialAmount());
                            entityList.add(couponEntityVO);
                        }
                    }
                    List<CouponEntityVO> sortedList = entityList.stream()
                            .sorted(Comparator.comparing(CouponEntityVO::getPreferentialContentType)
                                    .reversed())
                            .collect(Collectors.toList());

                    for (CouponEntityVO couponEntity : sortedList) {
                        Integer preferentialContentType = couponEntity.getPreferentialContentType();
                        CouponUpdateReturn couponUpdateReturn = new CouponUpdateReturn();
                        if (preferentialContentType == 1) {
                            BigDecimal marginPreference = couponEntity.getMarginPreference();
                            BigDecimal divide = marginPreference.divide(new BigDecimal(10));
                            BigDecimal one = BigDecimal.valueOf(1);
                            BigDecimal result = one.subtract(divide);
                            BigDecimal multiply = totalAmount.multiply(result);
                            couponUpdateReturn.setRealityPreferentialAmount(multiply);
                            couponUpdateReturn.setId(couponEntity.getCouponCustomerId());
                            totalAmount = totalAmount.subtract(multiply);
                            list.add(couponUpdateReturn);

                        } else {
                            BigDecimal marginPreference = couponEntity.getMarginPreference();
                            totalAmount = totalAmount.subtract(marginPreference);
                            if(totalAmount.compareTo(BigDecimal.ZERO) >=0){
                                couponUpdateReturn.setRealityPreferentialAmount(marginPreference);
                                couponUpdateReturn.setId(couponEntity.getCouponCustomerId());
                                list.add(couponUpdateReturn);
                            }else {
                                BigDecimal bigDecimal = totalAmount.add(marginPreference);
                                if(bigDecimal.compareTo(BigDecimal.ZERO)>0){
                                    couponUpdateReturn.setRealityPreferentialAmount(bigDecimal);
                                    couponUpdateReturn.setId(couponEntity.getCouponCustomerId());
                                    list.add(couponUpdateReturn);
                                    break;
                                }

                            }

                        }

                    }
                    for (CouponUpdateReturn couponUpdateReturn : list) {
                        BigDecimal realityPreferentialAmount = couponUpdateReturn.getRealityPreferentialAmount();
                        Long id = couponUpdateReturn.getId();
                        couponCustomerMapper.couponAddLock(id, realityPreferentialAmount, lockedTime, lockedDuration, relevanceBill, relevanceContract,billNo);
                    }
                }
            }
            return list;
        }


    }

    public Boolean couponUntieLock(CouponUnLockVo couponUnLockVo) {
        try (DistributeLock lock = DistributeLock.getLock(UNTIE_COUPONS_LOCK + ":" + SecurityFrameworkUtils.getLoginUserId())) {
            if (lock.tryLock()) {
                Set<Long> ids = couponUnLockVo.getIds();
                if (CollectionUtil.isNotEmpty(ids)) {
                    List<Long> list = new ArrayList<>(ids);
                    couponCustomerMapper.couponUntieLock(list);
                }
            }
        }
        return true;
    }

    public List<CouponSimpleInfoVo> checkBillCoupons(CouponCheckReqVo reqVo) {
        List<CouponCustomerValidQueryVo> list = memberCouponCustomerRepository.getCouponCustomerCoupons(reqVo.getTenantUserId());
        List<CouponSimpleInfoVo> result = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        for (CouponCustomerValidQueryVo item : list) {
            List<CouponApartmentVO> apartmentIds = item.getApartmentIds();
            //门店集合 只有内部员工券是不限门店-1，其他券都是适用一个或者多个门店没有-1的取值
            List<Long> collect = apartmentIds.stream().map(CouponApartmentVO::getApartmentId).collect(Collectors.toList());
            CouponSimpleInfoVo vo = new CouponSimpleInfoVo(item);
            if (item.getCouponType().intValue() == CouponTypeEnum.RESERVATION_DISCOUNT.getNum().intValue()
                    || item.getCouponType().intValue() == CouponTypeEnum.OLD_WITH_NEW_DISCOUNT.getNum().intValue()
                    || item.getCouponType().intValue() == CouponTypeEnum.NEW_SIGNING_DISCOUNT.getNum().intValue()
            ) {
                //券类型是预定，老带新，新签约，非本人、非活动门店、非使用时间 ,支持多门店
                if (!reqVo.getTenantUserId().equals(item.getUserId())
                        ||!collect.contains(reqVo.getStoreId())
                        || !CustomDateUtil.isBetween(item.getExpirationStartTime(), item.getExpirationEndTime(), now)
                ) {
                    vo.setFlag(false);
                    result.add(vo);
                    continue;
                }
            } else if (item.getCouponType().intValue() == CouponTypeEnum.INTERNAL_EMPLOYEE_DISCOUNT.getNum().intValue()) {
                if (!CustomDateUtil.isBetween(item.getExpirationStartTime(), item.getExpirationEndTime(), now)
                        || !reqVo.getTenantUserId().equals(item.getUserId())) {
                    vo.setFlag(false);
                    result.add(vo);
                    continue;
                }
            } else if (item.getCouponType().intValue() == CouponTypeEnum.OTHER_DISCOUNT.getNum().intValue()) {
                if (!CustomDateUtil.isBetween(item.getExpirationStartTime(), item.getExpirationEndTime(), now)
                        ||!collect.contains(reqVo.getStoreId())
                        || !reqVo.getTenantUserId().equals(item.getUserId())) {
                    vo.setFlag(false);
                    result.add(vo);
                    continue;
                }
            }
            vo.setFlag(true);
            result.add(vo);
        }
        if (result != null && result.size() > 0) {
            result = result.stream().filter(r -> r.getFlag()).collect(Collectors.toList());
        }

        return result;
    }

    public Boolean checkBillCouponsOverlay(CouponCheckReqVo reqVo) {
        List<Long> ids = reqVo.getCustomCouponVOS().stream().map(CustomCouponVO::getId).collect(Collectors.toList());
        List<CouponCustomerValidQueryVo> customerCoupons = memberCouponCustomerRepository.getCouponCustomerCouponsByIds(ids);
        LocalDateTime now = LocalDateTime.now();
        for (CouponCustomerValidQueryVo item : customerCoupons) {
            List<CouponApartmentVO> apartmentIds = item.getApartmentIds();
            //门店集合 只有内部员工券是不限门店-1，其他券都是适用一个或者多个门店没有-1的取值
            List<Long> collect = apartmentIds.stream().map(CouponApartmentVO::getApartmentId).collect(Collectors.toList());
            if (item.getCouponType().intValue() == CouponTypeEnum.RESERVATION_DISCOUNT.getNum().intValue()
                    || item.getCouponType().intValue() == CouponTypeEnum.OLD_WITH_NEW_DISCOUNT.getNum().intValue()
                    || item.getCouponType().intValue() == CouponTypeEnum.NEW_SIGNING_DISCOUNT.getNum().intValue()
            ) {
                //券类型是预定，老带新，新签约，非本人、非活动门店、非使用时间
                if (!reqVo.getTenantUserId().equals(item.getUserId())
                        ||!collect.contains(reqVo.getStoreId())
                        || !CustomDateUtil.isBetween(item.getExpirationStartTime(), item.getExpirationEndTime(), now)
                        || !CustomDateUtil.isBetween(item.getSigningStartTime(), item.getSigningEndTime(), now)
                ) {
                    log.error(item.getCouponName() + "不能用!");
                    throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), item.getCouponName() + "不能用!");
                } else if (item.getIsLocked()) {
                    log.error(item.getCouponName() + "已被锁定!");
                    throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), item.getCouponName() + "已被锁定");
                } else if (item.getUsageStatus().intValue() != CouponUsageStatusEnum.TO_BE_USED.getCode().intValue()) {
                    log.error(item.getCouponName() + "非待使用!");
                    throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), item.getCouponName() + "非待使用");
                }
            } else if (item.getCouponType().intValue() == CouponTypeEnum.INTERNAL_EMPLOYEE_DISCOUNT.getNum().intValue()) {
                if (!CustomDateUtil.isBetween(item.getExpirationStartTime(), item.getExpirationEndTime(), now)
                        || !reqVo.getTenantUserId().equals(item.getUserId())) {
                    log.error(item.getCouponName() + "不能用!");
                    throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), item.getCouponName() + "不能用!");
                } else if (item.getIsLocked()) {
                    log.error(item.getCouponName() + "已被锁定!");
                    throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), item.getCouponName() + "已被锁定");
                } else if (item.getUsageStatus().intValue() != CouponUsageStatusEnum.TO_BE_USED.getCode().intValue()) {
                    log.error(item.getCouponName() + "非待使用!");
                    throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), item.getCouponName() + "非待使用");
                }
            } else if (item.getCouponType().intValue() == CouponTypeEnum.OTHER_DISCOUNT.getNum().intValue()) {
                if (!CustomDateUtil.isBetween(item.getExpirationStartTime(), item.getExpirationEndTime(), now)
                        ||!collect.contains(reqVo.getStoreId())
                        || !reqVo.getTenantUserId().equals(item.getUserId())) {
                    log.error(item.getCouponName() + "不能用!");
                    throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), item.getCouponName() + "不能用!");
                } else if (item.getIsLocked()) {
                    log.error(item.getCouponName() + "已被锁定!");
                    throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), item.getCouponName() + "已被锁定");
                } else if (item.getUsageStatus().intValue() != CouponUsageStatusEnum.TO_BE_USED.getCode().intValue()) {
                    log.error(item.getCouponName() + "非待使用!");
                    throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), item.getCouponName() + "非待使用");
                }
            }
        }
        //叠加逻辑
        Map<Long, List<CustomCouponVO>> collect = reqVo.getCustomCouponVOS().stream().collect(Collectors.groupingBy(CustomCouponVO::getCouponId));
        Set<Long> couponIds = collect.keySet();
        if (reqVo.getCustomCouponVOS() != null && reqVo.getCustomCouponVOS().size() > 0) {
            //如果券种类原始数据有重复情况，那么如果含有[2]的就要抛异常 即couponIds.size<reqVo.getCustomCouponVOS().size()并且里面有[1]
            List<String> overlays = customerCoupons.stream().map(CouponCustomerValidQueryVo::getCouponUseOverlay).collect(Collectors.toList());
            //1.如果传的对象集合大于1,则需要判断,这其中有几种优惠券id
            if (reqVo.getCustomCouponVOS().size() > 1) {
                //选了多张券
                //如果券种类大于1
                if (couponIds != null && couponIds.size() > 1) {
                    //有多优惠活动
                    //那么只有其中有[]或者["1"]就不行
                    for (CouponCustomerValidQueryVo vo : customerCoupons) {
                        if (vo.getCouponUseOverlay().equals("[]") || vo.getCouponUseOverlay().equals("[1]")) {
                            log.error("含有只能单独使用或者含有只能同一活动叠加使用的券!");
                            //  return false;
                            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "含有只能单独使用或者含有只能同一活动叠加使用的券");
                        }
                    }

                    if (couponIds.size() < reqVo.getCustomCouponVOS().size()) {
                        //如果券种类原始数据有重复情况，那么如果含有[2]的就要抛异常 即couponIds.size<reqVo.getCustomCouponVOS().size()并且里面有[1]
                        if (overlays.contains("[1]")) {
                            for (CouponCustomerValidQueryVo vo : customerCoupons) {
                                if (vo.getCouponUseOverlay().equals("[2]")) {
                                    log.error("含有只能跨活动叠加使用的券");
                                    //  return false;
                                    throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "含有只能跨活动叠加使用的券");
                                }
                            }
                        } else if (overlays.contains("[2]")) {
                            //如果其中含有[2],并且其中[2]有重复
                            List<CouponCustomerValidQueryVo> vos = customerCoupons.stream().filter(c -> c.getCouponUseOverlay().equals("[2]")).collect(Collectors.toList());
                            //如果有重复
                            Map<Long, List<CouponCustomerValidQueryVo>> map = vos.stream().collect(Collectors.groupingBy(CouponCustomerValidQueryVo::getCouponId));
                            Set<Long> couponSet = map.keySet();
                            if (vos.size() > couponSet.size()) {
                                log.error("含有跨活动叠加使用的券");
                                //  return false;
                                throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "含有跨活动叠加使用的券");
                            }
                        }
                    }


                } else {
                    //只要一种优惠活动，这里肯定是多张券的,那么出现排他[]或者["2"]只能其他活动可叠加使用就就不行
                    for (CouponCustomerValidQueryVo vo : customerCoupons) {
                        if (vo.getCouponUseOverlay().equals("[]") || vo.getCouponUseOverlay().equals("[2]")) {
                            // return false;
                            log.error("含有只能单独使用或者只能跨活动叠加使用的券");
                            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "含有只能单独使用或者只能跨活动叠加使用的券");
                        }
                    }
                }

            } else {
                //只选了一张券
                return true;
            }

        }
        return true;
    }

    /**
     * 优惠劵优惠信息返回
     * @param couponLockVo
     * @return
     */
    public CouponReturn couponReturn(CouponLockVo couponLockVo) {
        List<CouponUpdateReturn> list = new ArrayList<>();
        try (DistributeLock lock = DistributeLock.getLock(ADD_COUPONS_LOCK + ":" + SecurityFrameworkUtils.getLoginUserId())) {
            if (lock.tryLock()) {
                BigDecimal totalAmount = couponLockVo.getTotalAmount();
                Set<Long> ids = couponLockVo.getIds();
                List<CustomCouponVO> customCouponVOS = new ArrayList<>();
                QueryWrapper<CouponCustomerEntity> qws = new QueryWrapper<>();
                qws.in("id",ids);
                List<CouponCustomerEntity> list1 = couponCustomerMapper.selectList(qws);
                for (CouponCustomerEntity couponCustomerEntity : list1) {
                    Long couponId = couponCustomerEntity.getCouponId();
                    Long id = couponCustomerEntity.getId();
                    CustomCouponVO vo = new CustomCouponVO();
                    vo.setCouponId(couponId);
                    vo.setId(id);
                    customCouponVOS.add(vo);
                }

                CouponCheckReqVo couponCheckReqVo = new CouponCheckReqVo();
                couponCheckReqVo.setCustomCouponVOS(customCouponVOS);
                couponCheckReqVo.setStoreId(couponLockVo.getStoreId());
                couponCheckReqVo.setTenantUserId(couponLockVo.getTenantUserId());
                Boolean aBoolean = checkBillCouponsOverlay(couponCheckReqVo);
                if (aBoolean) {
                    List<CouponEntityVO> entityList = new ArrayList<>();
                    for (CustomCouponVO customCouponVO : customCouponVOS) {
                        Long couponId = customCouponVO.getCouponId();
                        QueryWrapper<CouponCustomerEntity> qw =new QueryWrapper<>();
                        qw.eq("coupon_id",couponId);
                        List<CouponCustomerEntity> entities = couponCustomerMapper.selectList(qw);
                        if(CollectionUtil.isNotEmpty(entities)){
                            CouponCustomerEntity couponCustomerEntity = entities.get(0);
                            CouponEntityVO couponEntityVO = new CouponEntityVO();
                            couponEntityVO.setCouponCustomerId(customCouponVO.getId());
                            couponEntityVO.setPreferentialContentType(couponCustomerEntity.getPreferentialContentType());
                            couponEntityVO.setMarginPreference(couponCustomerEntity.getPreferentialAmount());
                            entityList.add(couponEntityVO);
                        }

                    }
                    List<CouponEntityVO> sortedList = entityList.stream()
                            .sorted(Comparator.comparing(CouponEntityVO::getPreferentialContentType)
                                    .reversed())
                            .collect(Collectors.toList());

                    for (CouponEntityVO couponEntity : sortedList) {
                        Integer preferentialContentType = couponEntity.getPreferentialContentType();
                        CouponUpdateReturn couponUpdateReturn = new CouponUpdateReturn();
                        if (preferentialContentType == 1) {
                            BigDecimal marginPreference = couponEntity.getMarginPreference();
                            BigDecimal divide = marginPreference.divide(new BigDecimal(10));
                            BigDecimal one = BigDecimal.valueOf(1);
                            BigDecimal result = one.subtract(divide);
                            BigDecimal multiply = totalAmount.multiply(result);
                            couponUpdateReturn.setRealityPreferentialAmount(multiply);
                            couponUpdateReturn.setId(couponEntity.getCouponCustomerId());
                            totalAmount = totalAmount.subtract(multiply);
                            list.add(couponUpdateReturn);

                        } else {
                            BigDecimal marginPreference = couponEntity.getMarginPreference();
                            totalAmount = totalAmount.subtract(marginPreference);
                            if(totalAmount.compareTo(BigDecimal.ZERO) >=0){
                                couponUpdateReturn.setRealityPreferentialAmount(marginPreference);
                                couponUpdateReturn.setId(couponEntity.getCouponCustomerId());
                                list.add(couponUpdateReturn);
                            }else {
                                BigDecimal bigDecimal = totalAmount.add(marginPreference);
                                if(bigDecimal.compareTo(BigDecimal.ZERO)>0){
                                    couponUpdateReturn.setRealityPreferentialAmount(bigDecimal);
                                    couponUpdateReturn.setId(couponEntity.getCouponCustomerId());
                                    list.add(couponUpdateReturn);
                                    break;
                                }

                            }

                        }

                    }

                }
            }
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (CouponUpdateReturn coupon : list) {
                BigDecimal preferentialAmount = coupon.getRealityPreferentialAmount();
                totalAmount = totalAmount.add(preferentialAmount);
            }
            CouponReturn couponReturn = new CouponReturn();
            couponReturn.setList(list);
            couponReturn.setTotalAmount(totalAmount);
            return couponReturn;
        }

    }

    public void updateUserId(Long oldUserId, Long userId, String userName, String mobile, String oldMobile) {
        couponCustomerMapper.updateUserId(oldUserId,userId,userName,mobile);
        couponRecordMapper.updateAccount(oldMobile,mobile);
    }

    public List<CouponCustomerVo> getCouponsByBill(String billId) {
       return baseMapper.getCouponsByBill(billId);
    }
}
